﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Collections;

namespace Pahan.McuFusion.DebugTools.Logging
{
    public class EventWriter<T> : IDisposable
    {
        public EventWriter(Stream output) : this(new StreamWriter(output))
        {
        }
        
        public EventWriter(StreamWriter output)
        {
            this.output = output;
            pollingThread = new Thread(Poll);
            pollingThread.Start();
        }

        public void Write(T @event)
        {
            queue.Enqueue(@event);
        }

        public void Start()
        {
            stopwatch.Start();
        }

        public void Stop()
        {
            stopwatch.Stop();
        }

        public void Reset()
        {
            stopwatch.Reset();
        }

        private void Poll()
        {
            do
            {
                T value;
                if (queue.TryDequeue(out value))
                {
                    output.Write(stopwatch.ElapsedTicks * 1000000 / Stopwatch.Frequency);
                    output.Write("@");
                    output.WriteLine(value.ToString());
                }
            } while (active);
        }

        private volatile bool active = true;

        private readonly Stopwatch stopwatch = new Stopwatch();

        private readonly ConcurrentQueue<T> queue = new ConcurrentQueue<T>();

        private readonly StreamWriter output;

        private readonly Thread pollingThread;

        #region Implementation of IDisposable

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        /// <filterpriority>2</filterpriority>
        public void Dispose()
        {
            active = false;
            pollingThread.Join();
            output.Dispose();
        }

        #endregion
    }
}